﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Input;
using System.Windows.Navigation;
using Microsoft.Phone.Controls;
using Sabang.Tools;
using System.Threading;
using System.Linq;

namespace Sabang
{
    public partial class Quran : PhoneApplicationPage
    {
        int _requestedPageNumber = Constant.START_PAGE;
        DataSourceLoader _dsLoader = new DataSourceLoader();
        TranslationLoader _tLoader;

        public Quran()
        {
            InitializeComponent();
        }

        /// <summary>
        /// On navigated to Quran, this page is expecting Quran's Page parameter.
        /// </summary>
        /// <param name="e"></param>
        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            IDictionary<string, string> parameters = this.NavigationContext.QueryString;

            if (parameters.ContainsKey(Constant.PAGE))
            {
                if (!Int32.TryParse(parameters[Constant.PAGE], out _requestedPageNumber))
                {
                    _requestedPageNumber = Constant.START_PAGE;
                }
            }

            base.OnNavigatedTo(e);

            if (!_dsLoader.Pages.ContainsKey(_requestedPageNumber))
            {
                _dsLoader.LoadPage(_requestedPageNumber);
            }

            loadSuras();
            loadPage();
        }

        private void loadSuras()
        {
            foreach (string key in _dsLoader.Suras.Keys)
            {
                //cbSurah.Items.Add(_dsLoader.Suras[key].name);
            }
        }

        private void loadPage()
        {
            Aya.FontSize = 25;
            Aya.FlowDirection = FlowDirection.RightToLeft; 
            this.Aya.Text = string.Empty;
            Aya.FontFamily = new System.Windows.Media.FontFamily("/Fonts/me_quran_volt_newmet.ttf#me_quran");
            tbPage.Text = _requestedPageNumber.ToString();// ArabicCharacterHelper.GetArabicNumber(_requestedPageNumber, _dsLoader.Numbers);

            //  Load selected Quran's page.
            quranPagesPage quranPage = _dsLoader.Pages[_requestedPageNumber];

            //  Set start and end of sura index.
            int startSuraIndex = Int32.Parse(quranPage.sura);
            int endSuraIndex = 0;

            //  If selected page is not last page then load next page information.
            quranPagesPage nextQuranPage = null;
            if (_requestedPageNumber < Constant.MAX_PAGE)
            {
                nextQuranPage = _dsLoader.Pages[_requestedPageNumber + 1];
                if (Int32.Parse(nextQuranPage.aya) > 1)
                {
                    endSuraIndex = Int32.Parse(nextQuranPage.sura);
                }
                else
                {
                    endSuraIndex = Int32.Parse(nextQuranPage.sura) - 1;
                }
            }
            else
            {
                endSuraIndex = Constant.MAX_SURA;// +1;
            }

            //  Set start sura and end sura.
            List<quranSurasSura> selectedSuras = new List<quranSurasSura>();

            if (endSuraIndex > startSuraIndex)
            {
                for (int i = startSuraIndex; i <= endSuraIndex; i++)
                //for (int i = startSuraIndex; i < endSuraIndex; i++)
                {
                    selectedSuras.Add(_dsLoader.Suras[i.ToString()]);
                }
            }
            else
            {
                selectedSuras.Add(_dsLoader.Suras[startSuraIndex.ToString()]);
            }

            //  Get ayas from the first sura.
            int startAyaIndex = Int32.Parse(quranPage.aya);
            int endAyaIndex;

            if (selectedSuras.Count > 1)
            {
                //  End aya index is the last aya.
                //endAyaIndex = Int32.Parse(selectedSuras[0].ayas);
                if (nextQuranPage != null)
                {
                    //  Check if next quran page is the same sura.
                    if (quranPage.sura == nextQuranPage.sura)
                    {
                        endAyaIndex = Int32.Parse(nextQuranPage.aya) - 1;
                    }
                    else
                    {
                        //  End aya index is the last aya.
                        endAyaIndex = Int32.Parse(selectedSuras[0].ayas);
                    }
                }
                else
                {
                    //  End aya index is the last aya.
                    endAyaIndex = Int32.Parse(selectedSuras[0].ayas);
                }
            }
            else 
            {
                if (nextQuranPage != null)
                {
                    //  Check if next quran page is the same sura.
                    if (quranPage.sura == nextQuranPage.sura)
                    {
                        endAyaIndex = Int32.Parse(nextQuranPage.aya) - 1;
                    }
                    else
                    {
                        //  End aya index is the last aya.
                        endAyaIndex = Int32.Parse(selectedSuras[0].ayas);
                    }
                }
                else
                {
                    //  End aya index is the last aya.
                    endAyaIndex = Int32.Parse(selectedSuras[0].ayas);
                }
            }

            StringBuilder sbQuran = new StringBuilder();
            quranSura qSura = _dsLoader.Quran[quranPage.sura];
            for (int i = startAyaIndex - 1; i < endAyaIndex; i++)
            {
                if (!string.IsNullOrEmpty(qSura.aya[i].bismillah))
                {
                    sbQuran.Append(qSura.aya[i].bismillah).Append("\n");
                }
                sbQuran.Append(qSura.aya[i].text).Append(" (").Append(ArabicCharacterHelper.GetArabicNumber(i+1, _dsLoader.Numbers)).Append(") ");
            }

            ////  Load first sura if loaded by page.
            //if (_isLoadByPage)
            //{
            //    _shownSura = Int32.Parse(selectedSuras[0].index);
            //}

            //  Process for the next sura.
            for (int i = 1; i < selectedSuras.Count; i++)
            {
                //  The start index will ALWAYS be 1.
                startAyaIndex = 1;

                if (i < selectedSuras.Count)
                {
                    //  End aya index is the last aya.
                    //endAyaIndex = Int32.Parse(selectedSuras[i].ayas);
                    if (nextQuranPage != null)
                    {
                        //  Check if next quran page is the same sura.
                        if (selectedSuras[i].index == nextQuranPage.sura)
                        {
                            endAyaIndex = Int32.Parse(nextQuranPage.aya) - 1;
                        }
                        else
                        {
                            //  End aya index is the last aya.
                            endAyaIndex = Int32.Parse(selectedSuras[i].ayas);
                        }
                    }
                    else
                    {
                        //  End aya index is the last aya.
                        endAyaIndex = Int32.Parse(selectedSuras[i].ayas);
                    }
                }
                else
                {
                    if (nextQuranPage != null)
                    {
                        //  Check if next quran page is the same sura.
                        if (selectedSuras[i].index == nextQuranPage.sura)
                        {
                            endAyaIndex = Int32.Parse(nextQuranPage.aya) - 1;
                        }
                        else
                        {
                            //  End aya index is the last aya.
                            endAyaIndex = Int32.Parse(selectedSuras[i].ayas);
                        }
                    }
                    else
                    {
                        //  End aya index is the last aya.
                        endAyaIndex = Int32.Parse(selectedSuras[i].ayas);
                    }
                }

                sbQuran.Append("\n");
                qSura = _dsLoader.Quran[selectedSuras[i].index];
                for (int j = startAyaIndex - 1; j < endAyaIndex; j++)
                {
                    if (!string.IsNullOrEmpty(qSura.aya[j].bismillah))
                    {
                        sbQuran.Append(qSura.aya[j].bismillah).Append("\n");
                    }
                    sbQuran.Append(qSura.aya[j].text).Append(" (").Append(ArabicCharacterHelper.GetArabicNumber(j + 1, _dsLoader.Numbers)).Append(") ");
                }

                
            }

            //  Load first sura if loaded by page.
            if (_isLoadByPage)
            {
                _shownSura = Int32.Parse(selectedSuras[selectedSuras.Count - 1].index);
            }

            this.Aya.Text = sbQuran.ToString();

            //  Update list of active sura.
            redSlider.Value = _shownSura;
            //tbSuraName.Text = _dsLoader.Suras[startSuraIndex.ToString()].name;
            //_shownSura = startSuraIndex;

            //_shownSura = startSuraIndex;
            tbSuraName.Text = _dsLoader.Suras[_shownSura.ToString()].name;
            tbSura.Text = _shownSura.ToString();
            //tbSura.Text = _dsLoader.Suras[startSuraIndex.ToString()].index;
        }

        private int _shownSura = 1;

        private void loadTranslation()
        {
            Aya.FontSize = 25;
            Aya.FlowDirection = FlowDirection.LeftToRight;
            Aya.FontFamily = new System.Windows.Media.FontFamily("/Fonts/akshar.ttf#Akshar Unicode");
            //Aya.FontFamily = new System.Windows.Media.FontFamily("Fonts/me_quran_volt_newmet.ttf#me_quran");
            
            //  Show tranlation here.
            if (_tLoader == null)
            {
                _tLoader = new TranslationLoader(ref _dsLoader);
            }

            this.Aya.Text = string.Empty;
            tbPage.Text = _requestedPageNumber.ToString();

            //  Load selected Quran's page.
            quranPagesPage quranPage = _dsLoader.Pages[_requestedPageNumber];

            //  Set start and end of sura index.
            int startSuraIndex = Int32.Parse(quranPage.sura);
            int endSuraIndex = 0;

            //  If selected page is not last page then load next page information.
            quranPagesPage nextQuranPage = null;
            if (_requestedPageNumber < Constant.MAX_PAGE)
            {
                nextQuranPage = _dsLoader.Pages[_requestedPageNumber + 1];
                endSuraIndex = Int32.Parse(nextQuranPage.sura);
            }
            else
            {
                endSuraIndex = Constant.MAX_SURA + 1;
            }

            //  Set start sura and end sura.
            List<quranSurasSura> selectedSuras = new List<quranSurasSura>();

            if (endSuraIndex > startSuraIndex)
            {
                for (int i = startSuraIndex; i < endSuraIndex; i++)
                {
                    selectedSuras.Add(_dsLoader.Suras[i.ToString()]);
                }
            }
            else
            {
                selectedSuras.Add(_dsLoader.Suras[startSuraIndex.ToString()]);
            }

            //  Get ayas from the first sura.
            int startAyaIndex = Int32.Parse(quranPage.aya);
            int endAyaIndex;

            if (selectedSuras.Count > 1)
            {
                //  End aya index is the last aya.
                endAyaIndex = Int32.Parse(selectedSuras[0].ayas);
            }
            else
            {
                if (nextQuranPage != null)
                {
                    //  Check if next quran page is the same sura.
                    if (quranPage.sura == nextQuranPage.sura)
                    {
                        endAyaIndex = Int32.Parse(nextQuranPage.aya) - 1;
                    }
                    else
                    {
                        //  End aya index is the last aya.
                        endAyaIndex = Int32.Parse(selectedSuras[0].ayas);
                    }
                }
                else
                {
                    //  End aya index is the last aya.
                    endAyaIndex = Int32.Parse(selectedSuras[0].ayas);
                }
            }

            StringBuilder sbQuran = new StringBuilder();
            quranSura qSura = _dsLoader.Quran[quranPage.sura];
            for (int i = startAyaIndex - 1; i < endAyaIndex; i++)
            {
                if (!string.IsNullOrEmpty(qSura.aya[i].bismillah))
                {
                    sbQuran.Append(qSura.aya[i].bismillah).Append("\n");
                }
                //sbQuran.Append(qSura.aya[i].text).Append(" (").Append(ArabicCharacterHelper.GetArabicNumber(i + 1, _dsLoader.Numbers)).Append(") ");
                sbQuran.Append(_tLoader.DictTranslations[quranPage.sura][i + 1]).Append(" (").Append(i + 1).Append(") ");
            }

            //  Process for the next sura.
            for (int i = 1; i < selectedSuras.Count; i++)
            {
                //  The start index will ALWAYS be 1.
                startAyaIndex = 1;

                if (i < selectedSuras.Count)
                {
                    //  End aya index is the last aya.
                    endAyaIndex = Int32.Parse(selectedSuras[i].ayas);
                }
                else
                {
                    if (nextQuranPage != null)
                    {
                        //  Check if next quran page is the same sura.
                        if (selectedSuras[i].index == nextQuranPage.sura)
                        {
                            endAyaIndex = Int32.Parse(nextQuranPage.aya) - 1;
                        }
                        else
                        {
                            //  End aya index is the last aya.
                            endAyaIndex = Int32.Parse(selectedSuras[i].ayas);
                        }
                    }
                    else
                    {
                        //  End aya index is the last aya.
                        endAyaIndex = Int32.Parse(selectedSuras[i].ayas);
                    }
                }

                sbQuran.Append("\n");
                qSura = _dsLoader.Quran[selectedSuras[i].index];
                for (int j = startAyaIndex - 1; j < endAyaIndex; j++)
                {
                    if (!string.IsNullOrEmpty(qSura.aya[j].bismillah))
                    {
                        sbQuran.Append(qSura.aya[j].bismillah).Append("\n");
                    }
                    //sbQuran.Append(qSura.aya[j].text).Append(" (").Append(ArabicCharacterHelper.GetArabicNumber(j + 1, _dsLoader.Numbers)).Append(") ");
                    sbQuran.Append(_tLoader.DictTranslations[selectedSuras[i].index][j + 1]).Append(" (").Append(j + 1).Append(") ");
                }
            }

            this.Aya.Text = sbQuran.ToString();
        }

        bool _isShowTranslation = false;

        private void Aya_ManipulationCompleted(object sender, ManipulationCompletedEventArgs e)
        {
            DateTime dtmStop = DateTime.Now;
            TimeSpan span = dtmStop - _dtmStart;

            if (span.TotalSeconds > 0.5)
            {
                //  Options.
                this.NavigationService.Navigate(new Uri("/QuranNavigator.xaml", UriKind.Relative));
            }
            else{

                _isLoadByPage = true;
            //  If tap: Translation OR Page.
                if (e.TotalManipulation.Translation.X == 0 && e.TotalManipulation.Translation.Y == 0)
                {
                    if (!_isShowTranslation)
                    {
                        loadTranslation();
                        _isShowTranslation = true;
                    }
                    else
                    {
                        loadPage();
                        _isShowTranslation = false;
                    }
                }
                else
                {
                    //  This is a tolerance value to move right and left. 
                    //  Since we don't want to change the page if user move UP and DOWN (assumption that the Y value will be GT 100).
                    if (Math.Abs(e.TotalManipulation.Translation.Y) < 100)
                    {
                        //  If touch goes right then next page.
                        if (e.TotalManipulation.Translation.X > 0)
                        {
                            if (_requestedPageNumber < Constant.MAX_PAGE)
                            {
                                _requestedPageNumber++;
                            }
                            else
                            {
                                _requestedPageNumber = Constant.START_PAGE;
                            }
                        }
                        else if (e.TotalManipulation.Translation.X < 0)
                        {
                            if (_requestedPageNumber > Constant.START_PAGE)
                            {
                                _requestedPageNumber--;
                            }
                            else
                            {
                                _requestedPageNumber = Constant.MAX_PAGE;
                            }
                        }

                        if (!_dsLoader.Pages.ContainsKey(_requestedPageNumber) || !_dsLoader.Pages.ContainsKey(_requestedPageNumber + 1))
                        {
                            _dsLoader.LoadPage(_requestedPageNumber);
                        }

                        if (!_isShowTranslation)
                        {
                            loadPage();
                        }
                        else
                        {
                            loadTranslation();
                        }
                    }
                }

                _isLoadByPage = false;
            }
        }

        DateTime _dtmStart;

        private void Aya_ManipulationStarted(object sender, ManipulationStartedEventArgs e)
        {
            _dtmStart = DateTime.Now;
        }

        private bool _isPageNeedToChange = true;

        //private void tbPage_TextChanged(object sender, System.Windows.Controls.TextChangedEventArgs e)
        //{
        //    if (_isPageNeedToChange)
        //    {
        //        _isPageNeedToChange = false;
        //        int requestedPageNumber;
        //        if (Int32.TryParse(tbPage.Text, out requestedPageNumber))
        //        {
        //            if (requestedPageNumber < 1)
        //            {
        //                _requestedPageNumber = Constant.MAX_PAGE;
        //            }
        //            else if (requestedPageNumber > Constant.MAX_PAGE)
        //            {
        //                _requestedPageNumber = 1;
        //            }
        //            else
        //            {
        //                _requestedPageNumber = requestedPageNumber;
        //            }

        //            if (!_dsLoader.Pages.ContainsKey(_requestedPageNumber) || !_dsLoader.Pages.ContainsKey(_requestedPageNumber + 1))
        //            {
        //                _dsLoader.LoadPage(_requestedPageNumber);
        //            }

        //            if (!_isShowTranslation)
        //            {
        //                loadPage();
        //            }
        //            else
        //            {
        //                loadTranslation();
        //            }

        //            redSlider.Value = _shownSura;
        //            _isRedSliderNeedToChange = false;
        //            tbSura.Text = _shownSura.ToString();
        //            _isTbSuraNeedToChange = false;
        //        }
        //    }

        //    if (!_isPageNeedToChange)
        //    {
        //        _isPageNeedToChange = true;
        //    }
        //}

        

        //private void tbSura_TextChanged(object sender, System.Windows.Controls.TextChangedEventArgs e)
        //{
        //    //if (_isTbSuraNeedToChange)
        //    //{
        //    //    int sura;
        //    //    if (Int32.TryParse(tbSura.Text, out sura))
        //    //    {
        //    //        if (sura >= Constant.MIN_SURA && sura <= Constant.MAX_SURA)
        //    //        {
        //    //            loadSura(sura);
        //    //        }
        //    //    }

        //    //    //  Change slider value.
        //    //    redSlider.Value = sura;
        //    //    _isRedSliderNeedToChange = false;
        //    //}

        //    //if (!_isTbSuraNeedToChange)
        //    //{
        //    //    _isTbSuraNeedToChange = true;
        //    //}

        //    int sura;
        //    if (Int32.TryParse(tbSura.Text, out sura))
        //    {
        //        if (sura >= Constant.MIN_SURA && sura <= Constant.MAX_SURA)
        //        {
        //            _shownSura = sura;
        //        }
        //    }

        //    loadSura(_shownSura);

        //}

        private void loadSura(int suraNumber)
        {
            if (_dsLoader.Pages.Count > 0)
            {
                //  Get the sura number.
                quranPagesPage page = _dsLoader.Pages.Values.Where(v => Int32.Parse(v.sura) == suraNumber).OrderBy(v => Int32.Parse(v.sura)).FirstOrDefault();

                if (page != null)
                {
                    if (Int32.Parse(page.aya) == 1)
                    {
                        _requestedPageNumber = Int32.Parse(page.index);
                    }
                    else
                    {
                        _requestedPageNumber = Int32.Parse(page.index) - 1;
                    }


                    if (!_dsLoader.Pages.ContainsKey(_requestedPageNumber) || !_dsLoader.Pages.ContainsKey(_requestedPageNumber + 1))
                    {
                        _dsLoader.LoadPage(_requestedPageNumber);
                    }
                }
                else
                {
                    //  Load Sura.
                    _requestedPageNumber = _dsLoader.LoadSuraStartPage(suraNumber);
                }

                loadPage();
            }
        }

        private void redSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            //if (_isRedSliderNeedToChange)
            //{
            //    int sura = (int)Math.Round(e.NewValue);
            //    loadSura(sura);

            //    if (tbSura != null)
            //    {
            //        tbSura.Text = sura.ToString();
            //        _isTbSuraNeedToChange = false;
            //    }
            //}

            //if (!_isRedSliderNeedToChange)
            //{
            //    _isRedSliderNeedToChange = true;
            //}

            _shownSura = (int)Math.Round(e.NewValue);
            loadSura(_shownSura);
        }

        private void btnPlus_Click(object sender, RoutedEventArgs e)
        {
            if (_shownSura < Constant.MAX_SURA)
            {
                _shownSura++;
            }
            else
            {
                _shownSura = 1;
            }

            loadSura(_shownSura);
        }

        private void btnMin_Click(object sender, RoutedEventArgs e)
        {
            if (_shownSura > 1)
            {
                _shownSura--;
            }
            else
            {
                _shownSura = Constant.MAX_SURA;
            }

            loadSura(_shownSura);
        }

        private void tbSura_LostFocus(object sender, RoutedEventArgs e)
        {
            int sura;
            if (Int32.TryParse(tbSura.Text, out sura))
            {
                if (sura >= Constant.MIN_SURA && sura <= Constant.MAX_SURA)
                {
                    _shownSura = sura;
                }
            }

            loadSura(_shownSura);
        }

        private bool _isLoadByPage = false;

        private void tbPage_LostFocus(object sender, RoutedEventArgs e)
        {
            //if (_isPageNeedToChange)
            //{
            //    _isPageNeedToChange = false;
                int requestedPageNumber;
                if (Int32.TryParse(tbPage.Text, out requestedPageNumber))
                {
                    if (requestedPageNumber < 1)
                    {
                        _requestedPageNumber = Constant.MAX_PAGE;
                    }
                    else if (requestedPageNumber > Constant.MAX_PAGE)
                    {
                        _requestedPageNumber = 1;
                    }
                    else
                    {
                        _requestedPageNumber = requestedPageNumber;
                    }

                    if (!_dsLoader.Pages.ContainsKey(_requestedPageNumber) || !_dsLoader.Pages.ContainsKey(_requestedPageNumber + 1))
                    {
                        _dsLoader.LoadPage(_requestedPageNumber);
                    }

                    _isLoadByPage = true;
                    if (!_isShowTranslation)
                    {
                        loadPage();
                    }
                    else
                    {
                        loadTranslation();
                    }
                    _isLoadByPage = false;

                    //redSlider.Value = _shownSura;
                    //_isRedSliderNeedToChange = false;
                    //tbSura.Text = _shownSura.ToString();
                    //_isTbSuraNeedToChange = false;
                }
            //}

            //if (!_isPageNeedToChange)
            //{
            //    _isPageNeedToChange = true;
            //}
        }

        
    }
}